import java.awt.image.BufferedImage;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import processing.core.PApplet;

public class Analyser {
	private static Analyser _analyser = null;
	public int _iterationCount;
	
	// Ausgangswerte aus der Datei
	public String _startHeadline;
	public String _startSubHeadline;
	public String _startTextArea;
	public String _startDate;
	public String _startPlace;
	public String _startImagePath;
	
	// Auswertungsdaten Headline
	public int _averageLengthHead;
	public int _averageCharacterHead;
	public int _wordCountHead;
	public int _longestWordLengthHead;
	public int _shortestWordLengthHead;
	public int[] _averageWordLengthHead;
	public int[] _averageWordCharacterHead;
	
	// Auswertungsdaten Subheadline
	public int _averageLengthSub;
	public int _averageCharacterSub;
	public int _wordCountSub;
	public int _longestWordLengthSub;
	public int _shortestWordLengthSub;
	public int[] _averageWordLengthSub;
	public int[] _averageWordCharacterSub;

	// Auswertungdaten TextArea
	public int _averageLengthArea;
	public int _averageCharacterArea;
	public int _wordCountArea;
	public int _shortestWordLengthTextArea;
	
	// Auswertungsdaten Datum
	public int _crossSumDate;
	public int _sumDate;
	public int _monthDate;
	public int _dayDate;
	public int _yearDate;
	
	// Auswertungsdaten Image
	public BufferedImage _image;
	public int _pixelCount;
	public Color[] _horizontalLine;
	public Color[] _verticalLine;
	public Color[][] _pixelImage;

	public Analyser(String headl, String subheadl, String textArea, String date,
			String place, String imagePath) {
		_startHeadline = headl;
		_startSubHeadline = subheadl;
		_startTextArea = textArea;
		_startDate = date;
		_startPlace = place;
		_startImagePath = imagePath;
		
		_analyser = this;
		
		startAnalyse();
	}

	private void startAnalyse() {
		analyseHeadline();
		analyseSubHeadline();
		analysetextArea();
		analyseDate();
		analyseImage();

		createImage();
	}

	private void analyseImage() {
		_image = bufferImage(_startImagePath);
		_image = resize(_image, 400, 700);

	}
	
    private BufferedImage resize(BufferedImage img, int newW, int newH) {  
        BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
        int w = img.getWidth();  
        int h = img.getHeight();  
        Graphics2D g = dimg.createGraphics();  
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);  
        g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);  
        g.dispose();
        return dimg;  
    }  

	private void analyseDate() {
		_dayDate = day(_startDate);
		_monthDate = month(_startDate);
		_yearDate = year(_startDate);
		_crossSumDate = crossSumDate(_startDate);
		_sumDate = sumDate(_startDate);
	}

	private void analysetextArea() {
		_averageLengthArea = averageLength(_startTextArea);
		_averageCharacterArea = averageCaracter(_startTextArea);
		_wordCountArea = wordCount(_startTextArea);
		_shortestWordLengthTextArea = shortestWordLength(_startTextArea);
	}

	private void analyseHeadline() {
		_averageLengthHead = averageLength(_startHeadline);
		_averageCharacterHead = averageCaracter(_startHeadline);
		_wordCountHead = wordCount(_startHeadline);
		_longestWordLengthHead = longestWordLength(_startHeadline);
		_shortestWordLengthHead = shortestWordLength(_startHeadline);
		_averageWordLengthHead = averageWordLength(_startHeadline);
		_averageWordCharacterHead = avarageWordCharacter(_startHeadline);
	}

	private void analyseSubHeadline() {
		_averageLengthSub = averageLength(_startSubHeadline);
		_averageCharacterSub = averageCaracter(_startSubHeadline);
		_wordCountSub = wordCount(_startSubHeadline);
		_longestWordLengthSub = longestWordLength(_startSubHeadline);
		_shortestWordLengthSub = shortestWordLength(_startSubHeadline);
		_averageWordLengthSub = averageWordLength(_startSubHeadline);
		_averageWordCharacterSub = avarageWordCharacter(_startSubHeadline);
	}

	private void createImage() {
		PApplet.main(new String[] { "--bgcolor=#ECE9D8", "Visualizer" });
	}
	
	private int[] avarageWordCharacter(String startHeadline) {
		int count = 0;
		
		if (startHeadline.equalsIgnoreCase(_startHeadline)) {
			count = _wordCountHead;
		}
		
		if (startHeadline.equalsIgnoreCase(_startSubHeadline)) {
			count = _wordCountSub;
		}
		
		
		
		if (count != 0) {
			int[] array = new int[count];
		
			int avarage = 0;
			int help = 0;
			int j = 0;
			
			String headline = startHeadline;
			headline = headline.toUpperCase();
			
			char[] charArray = headline.toCharArray();
			
			for (int i = 0; i < charArray.length; i++) {
				int intChar = charArray[i];
				intChar = intChar - 64;
				
				if (charArray[i] != ' ') {
					avarage += intChar;
					help++;
				} else {
					if (help != 0) {
						avarage = avarage / help;
						array[j] = avarage;
						j++;
					}
					help = 0;
					avarage = 0;
				}
			}
			
			if (help != 0) {
				avarage = avarage / help;
				array[j] = avarage;
			}
			
			return array;
		}
				
		return null;
	}

	private int[] averageWordLength(String startHeadline) {
		int count = 0;
		
		if (startHeadline.equalsIgnoreCase(_startHeadline)) {
			count = _wordCountHead;
		}
		
		if (startHeadline.equalsIgnoreCase(_startSubHeadline)) {
			count = _wordCountSub;
		}
		
		if (count != 0) {
			int[] array = new int[count];
		
			int average = 0;
			int j = 0;
			
			char[] charArray = startHeadline.toCharArray();
			
			for (int i = 0; i < charArray.length; i++) {
				if(!(charArray[i] == ' ')) {
					average++;
				} else {
					if (average != 0) {
						array[j++] = average;
					}
					average = 0;
				}
			}
			
			if ((charArray[charArray.length-1] != ' ')) {
				array[j] = average;
			}
			
			return array;
		}
				
		return null;
	}

	private int shortestWordLength(String startHeadline) {
		int average = 1;
		int help = 0;
		boolean wortSet = false;
		
		char[] charArray = startHeadline.toCharArray();
		
		for (int i = 0; i < charArray.length; i++) {
			if(!(charArray[i] == ' ')) {
				help++;
			} else {
				if (average == 1) {
					average = help;
					wortSet = true;
				}
				
				if(help < average) {
					wortSet = true;
					average = help;
				}
				
				help = 0;
			}
		}
		
		if(help < average && help != 0) {
			average = help;
			wortSet = true;
		}
		
		if(!wortSet) {
			average = help;
		}
		
		return average;
	}

	private int longestWordLength(String startHeadline) {
		int average = 1;
		int help = 0;
		boolean wortSet = false;
		
		char[] charArray = startHeadline.toCharArray();
		
		for (int i = 0; i < charArray.length; i++) {
			if(!(charArray[i] == ' ')) {
				help++;
			} else {
				if(help > average) {
					average = help;
					wortSet = true;
				}
				help = 0;
			}
		}
		
		if(help > average) {
			average = help;
			wortSet = true;
		}
		
		if(!wortSet) {
			average = help;
		}
		
		return average;
	}

	private int wordCount(String startHeadline) {
		int count = 0;
		boolean check = false;
	
		char[] charArray = startHeadline.toCharArray();
		
		if (charArray.length != 0) {
			for (int i = 0; i < charArray.length; i++) {
				if (charArray[i] != ' ') {
					check = true;
				}
				
				if (charArray[i] == ' ' && check == true) {
					count++;
					check = false;
				}
				
				if (i == charArray.length - 1 && charArray[i] != ' ') {
					count++;
				}
			}
		}
		
		if (count == 0) {
			count = 1;
		}
		
		return count;
	}

	private int averageCaracter(String startHeadline) {
		int average = 0;
		int help = 0;
		String headline = startHeadline;
		headline = headline.toUpperCase();
		
		char[] charArray = headline.toCharArray();
		
		for (int i = 0; i < charArray.length; i++) { 
			int intChar = charArray[i];
			intChar = intChar - 64;
			
			if (charArray[i] != ' ') {
				average += intChar;
				help++;
			}
		}
		
		if (help != 0) {
			average = average / help;
		}
		
		if(average == 0) {
			average = 1;
		}
		
		return average;
	}

	private int averageLength(String startHeadline) {
		return startHeadline.replaceAll(" ", "").toCharArray().length;
	}

	//dd.mm.yyyy
	private int year(String startDate) {
		int year = 1;
		int help = 0;
		
		char[] array = startDate.toCharArray();
		
		for (int i = 0; i < array.length; i++) {
			if (array[i] == '.') {
				help++;
				
				if (help == 2) {
					try {
						return Integer.valueOf(startDate.substring(i+1));
					} catch (Exception e) {}
				}
			}
		}
		
		return year;
	}

	private int day(String startDate) {
		int day = 1;
		
		char[] array = startDate.toCharArray();
		
		for (int i = 0; i < array.length; i++) {
			if (array[i] == '.') {
				try {
					return Integer.valueOf(startDate.substring(0, i));
				} catch (Exception e) {}
			}
		}
		
		return day;
	}

	private int month(String startDate) {
		int month = 1;
		int help1 = 0;
		int help2 = 0;
		
		char[] array = startDate.toCharArray();
		
		for (int i = 0; i < array.length; i++) {
			if (array[i] == '.') {
				if (help1 == 0) {
					help1 = i;
				} else if (help1 > 0) {
					help2 = i;
				}
				
				
				if (help1 != 0 && help2 != 0) {
					try {
						return Integer.valueOf(startDate.substring(help1+1, help2));
					} catch (Exception e) {}
				}
			}
		}
		
		return month;
	}

	private int crossSumDate(String startDate) {
		int cross = 1;
		String date = startDate.replaceAll("\\.", "");
		char[] array = date.toCharArray();
		
		for (int i = 0; i < array.length; i++) {
			try {
				cross += Integer.valueOf(array[i]-48);
			} catch (Exception e) {}
		}
		
		return cross;
	}

	private int sumDate(String startDate) {
		return _dayDate+_monthDate+_yearDate;
	}
	
	public Color[][] pixelImage(int pixel) {
		Color[][] color = new Color[(int) _image.getWidth() / pixel ][(int) _image.getHeight() / pixel]; 

		int xPos = 0;
		int yPos = 0;
		
		int x = 0;
		int y = 0;
		
		while (x < _image.getWidth()) {
			while (y < _image.getHeight()) {
				if (x == 540) {
					System.out.println();
				}
				color[xPos][yPos] = getPixel(x, y, pixel);
				
				y += pixel;
				yPos++;
			}
			x += pixel;
			xPos++;
			
			y = 0;
			yPos = 0;
		}
		
		return color;
	}
	
	private Color getPixel(int x, int y, int pixel) {
		Color c;
		float r = 0;
		float g = 0;
		float b = 0;
		
		int posY = y;
		
		for (int i = 1; i <= pixel; i++) {
			for (int j = 1; j <= pixel; j++) {
				int rgb = _image.getRGB(x, posY);
				c = new Color(rgb);
				
				r += c.getRed();
				g += c.getGreen();
				b += c.getBlue();
				
				posY++;
			}
			posY = y;
			x++;
		}
		
		r = r / (pixel * pixel);
		g = g / (pixel * pixel);
		b = b / (pixel * pixel);
		
		return new Color((int) r, (int) g, (int) b);
	}

	// [v][h]
	public Color[] verticalLine(int pixel) {
		Color[] color = new Color[_image.getWidth(null)];
		Color c;
		float r = 0;
		float g = 0;
		float b = 0;
		
		for (int i = 0; i < _image.getWidth(null); i++) {
			r = 0;
			g = 0;
			b = 0;
			
			for (int j = 0; j < _image.getHeight(null); j++) {
				int rgb = _image.getRGB(i, j);
				c = new Color(rgb);
				
				r += c.getRed();
				g += c.getGreen();
				b += c.getBlue();
				
				if (j == _image.getHeight(null) - 1) {
					r = r / _image.getHeight(null);
					g = g / _image.getHeight(null);
					b = b / _image.getHeight(null);
					
					color[i] = new Color((int) r, (int) g, (int) b);
				}
			}
		}
		
		Color[] average = new Color[_image.getWidth(null) / pixel];
		int av = 0;
		
		r = 0;
		g = 0;
		b = 0;
		
		for (int j = 1; j <= color.length; j++) {
			r += color[j-1].getRed();
			g += color[j-1].getGreen();
			b += color[j-1].getBlue();
				
			if ((j % pixel) == 0) {
				r = r / pixel;
				g = g / pixel;
				b = b / pixel;
				
				average[av] = new Color((int) r, (int) g, (int) b);
				av++;
				r = 0;
				g = 0;
				b = 0;
			}
		}
		
		return average;
	}
	
	public Color[] horizontalLine(int pixel) {
		Color[] color = new Color[_image.getHeight(null)];
		Color c;
		float r = 0;
		float g = 0;
		float b = 0;
		
		for (int i = 0; i < _image.getHeight(null); i++) {
			r = 0;
			g = 0;
			b = 0;
			
			for (int j = 0; j < _image.getWidth(null); j++) {
				int rgb = _image.getRGB(j, i);
				c = new Color(rgb);
				
				r += c.getRed();
				g += c.getGreen();
				b += c.getBlue();
				
				if (j == _image.getWidth(null) - 1) {
					r = r / _image.getWidth(null);
					g = g / _image.getWidth(null);
					b = b / _image.getWidth(null);
					
					color[i] = new Color((int) r, (int) g, (int) b);
				}
			}
		}
		
		Color[] average = new Color[_image.getHeight(null) / pixel];
		int av = 0;
		
		r = 0;
		g = 0;
		b = 0;
		
		for (int j = 1; j <= color.length; j++) {
			r += color[j-1].getRed();
			g += color[j-1].getGreen();
			b += color[j-1].getBlue();
				
			if ((j % pixel) == 0) {
				r = r / pixel;
				g = g / pixel;
				b = b / pixel;
				
				average[av] = new Color((int) r, (int) g, (int) b);
				av++;
				r = 0;
				g = 0;
				b = 0;
			}
		}
		
		return average;
	}
	
	public Color getAverageColor() {
		Color c;
		int r = 0;
		int g = 0;
		int b = 0;

		for (int x = 0; x < _image.getWidth(); x++) {
			for (int y = 0; y < _image.getHeight(); y++) {
				c = new Color(_image.getRGB(x, y));
				r += c.getRed();
				g += c.getGreen();
				b += c.getBlue();
			}
		}

		r = r / _pixelCount;
		g = g / _pixelCount;
		b = b / _pixelCount;

		return new Color(r, g, b);
	}

	public Color getComplementaryColor() {
		Color c = getAverageColor();
		
		int r = Math.abs((c.getRed() - 255) % 255);
		int g = Math.abs((c.getGreen() - 255) % 255);
		int b = Math.abs((c.getBlue() - 255) % 255);

		return new Color(r, g, b);
	}

	private BufferedImage bufferImage(String startImagePath) {
		BufferedImage img = null;
		try {
			img = ImageIO.read(new File(startImagePath));
			_pixelCount = img.getHeight(null) * img.getWidth(null);
		} catch (IOException e) {}
		return img;
	}
	
	public static Analyser getInstance() {
		return _analyser;
	}
}